package cn.itcast.nems.employee.service.impl;

import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.enumeration.BaseErrorBodyEnum;
import cn.itcast.nems.employee.dao.entity.Employee;
import cn.itcast.nems.employee.dao.mapper.EmployeeMapper;
import cn.itcast.nems.employee.dto.EmployeeDTO;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.manager.redis.RedisUtil;
import cn.itcast.nems.manager.redis.constant.RedisKeyConstant;
import cn.itcast.nems.manager.util.CustomBeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
    private final RedisUtil redisUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkAndSaveEmployee(EmployeeDTO employeeDTO) {
        log.info("[检查并持久化员工信息] 参数: {}", JSON.toJSONString(employeeDTO));
        String redisKey = CustomBeanUtil.append("|", RedisKeyConstant.REDIS_EMPLOYEE_COUNT, employeeDTO.getJobNumber());
        Long count = 0L;
        // 检查数据库中该工作邮箱是否存在
        if (redisUtil.hasKey(redisKey)) {
            count = Long.valueOf(redisUtil.get(redisKey).toString());
        } else {
            count = getBaseMapper().selectCount(new LambdaQueryWrapper<Employee>()
                    .eq(Employee::getEmail, employeeDTO.getEmail()).eq(Employee::getDeletedFlag, false));
            try {
                redisUtil.set(redisKey, count, 5 * 60);
            } catch (Exception e) {
                BizExceptionProducer.throwProduce(e, BaseErrorBodyEnum.REDIS_ERROR);
            }
        }
        log.info("[检查并持久化员工信息] 查询参数: {} , 查询结果: {}", employeeDTO.getEmail(), count);
        if (count == 0) {
            Employee employee = CustomBeanUtil.copyProperties(employeeDTO, new Employee());
            int insetResult = getBaseMapper().insert(employee);
            Assert.isTrue(insetResult > 0, BizExceptionProducer.serverError("持久化员工表失败, 参数: %s", JSON.toJSONString(employeeDTO)));
            redisUtil.del(redisKey);
        }
    }

    @Override
    public Employee findOneByEmail(String email) {
        if (StringUtils.isBlank(email)) {
            return null;
        }
        if (redisUtil.hasKey(email)) {
            return (Employee) redisUtil.get(email);
        }
        Employee employee = getBaseMapper().findOneByEmail(email);
        if (Objects.nonNull(employee)) {
            try {
                redisUtil.set(email, employee, 5 * 60);
            } catch (Exception e) {
                BizExceptionProducer.throwProduce(e, BaseErrorBodyEnum.REDIS_ERROR);
            }
        }
        return employee;
    }

    @Override
    public List<Employee> findByName(String name) {
        if (StringUtils.isBlank(name)) {
            return Collections.emptyList();
        }

        return getBaseMapper().selectList(new LambdaQueryWrapper<Employee>()
                .eq(Employee::getName, name)
                .eq(Employee::getStatus, 1)
                .eq(Employee::getDeletedFlag, false));
    }

    @Override
    public List<Employee> findMoreByEmail(Collection<String> email) {
        if (email == null) return null;
        if (email.isEmpty()) return List.of();
        return getBaseMapper().findMoreByEmail(email);
    }

    @Override
    public void created(Employee employee) {
        String email = employee.getEmail();
        if (checkEmail(employee.getId(), email)) {
            return;
        }
        employee.setCreatedBy(email);
        employee.setModifiedBy(email);
        employee.setId(UUID.randomUUID().toString().replace("-", ""));
        employee.setCreatedDatetime(LocalDateTime.now());
        baseMapper.insert(employee);
    }

    private Boolean checkEmail(String id, String email) {
        org.springframework.util.Assert.hasText(email, "邮箱不能为空");
        return lambdaQuery()
                .eq(Employee::getEmail, email)
                // 过滤掉修改本身
                .ne(org.springframework.util.StringUtils.hasText(id), Employee::getId, id)
                .exists();
    }

    @Override
    public void updateStatus(String id, Integer status) {
        Employee employee = new Employee();
        employee.setId(id);
        employee.setStatus(status);
        employee.setResignTime(LocalDateTime.now());
        employee.setModifiedDatetime(LocalDateTime.now());
        getBaseMapper().updateById(employee);
    }

    @Override
    public void update(Employee employee) {
        String email = employee.getEmail();
        if (checkEmail(employee.getId(), email)) {
            return;
        }
        employee.setModifiedDatetime(LocalDateTime.now());
        baseMapper.updateById(employee);
    }
}
